﻿using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Windows.Forms;

namespace Boxie
{
    class BoxieLib
    {
        private static string SmartTypingHeader;

        public static int ReturnFileType(string f)
        {
            // return values
            //   0 - directory
            //   1 - image
            //   2 - other
            string ext = System.IO.Path.GetExtension(f);
            switch (ext.ToLower())
            {
                case "":
                    return 0;
                case ".jpg":
                    return 1;
                case ".jpeg":
                    return 1;
                case ".png":
                    return 1;
                case ".ico":
                    return 1;
                case ".bmp":
                    return 1;
                case ".tiff":
                    return 1;
                case ".gif":
                    return 1;
                default:
                    return 2;
            }
        }

        public static void SaveClipboardImage(frmBoxie b, string loc)
        {
            Image img = Clipboard.GetImage();
            img.Save(loc, System.Drawing.Imaging.ImageFormat.Png);
            img.Dispose();
            b.appargs = BoxieLib.MergeArrays(b.appargs, new string[1] { loc });
            if (b.fQ != null)
            {
                if (b.fQ.Visible)
                {
                    b.fQ.lst.Items.Clear();
                    for (int x = 0; x <= b.appargs.GetUpperBound(0); x++)
                        b.fQ.lst.Items.Add(b.appargs[x]);
                }
            }

            b.Text = b.appnamebuild + b.appargs.Length + " Files Loaded";
        }

        public static void SaveClipboardText(frmBoxie b, string loc)
        {
            string Txt = Clipboard.GetText();
            System.IO.TextWriter tw = new System.IO.StreamWriter(loc);
            tw.Write(Txt);
            tw.Close();
            tw.Dispose();
            b.appargs = BoxieLib.MergeArrays(b.appargs, new string[1] { loc });
            if (b.fQ != null)
            {
                if (b.fQ.Visible)
                {
                    b.fQ.lst.Items.Clear();
                    for (int x = 0; x <= b.appargs.GetUpperBound(0); x++)
                        b.fQ.lst.Items.Add(b.appargs[x]);
                }
            }

            b.Text = b.appnamebuild + b.appargs.Length + " Files Loaded";
        }

        public static string[] MergeArrays(string[] arrayone, string[] arraytwo)
        {
            ArrayList al = new ArrayList();
            bool found;
            for (int x = 0; x <= arraytwo.GetUpperBound(0); x++)
            {
                found = false;
                for (int y = 0; y <= arrayone.GetUpperBound(0); y++)
                    if (arrayone[y] == arraytwo[x])
                        found = true;
                if (!found)
                    if(ReturnFileType(arraytwo[x])>0)
                        al.Add(arraytwo[x]);
                    
            }
            if (al.Count == 0)
                return arrayone;
            else
            {
                string[] tmp = new string[arrayone.Length + al.Count];
                for (int x = 0; x <= arrayone.GetUpperBound(0); x++)
                    tmp[x] = arrayone[x];
                for (int x = 0; x < al.Count; x++)
                    tmp[arrayone.Length + x] = (string)al[x];
                return tmp;
            }
        }

        public static Bitmap MakeGrayscale(Bitmap original)
        {
            //create a blank bitmap the same size as original
            Bitmap newBitmap = new Bitmap(original.Width, original.Height);

            //get a graphics object from the new image
            Graphics g = Graphics.FromImage(newBitmap);

            //create the grayscale ColorMatrix
            ColorMatrix colorMatrix = new ColorMatrix(
               new float[][] 
                  {
                     new float[] {.3f, .3f, .3f, 0, 0},
                     new float[] {.59f, .59f, .59f, 0, 0},
                     new float[] {.11f, .11f, .11f, 0, 0},
                     new float[] {0, 0, 0, 1, 0},
                     new float[] {0, 0, 0, 0, 1}
                  });

            //create some image attributes
            ImageAttributes attributes = new ImageAttributes();

            //set the color matrix attribute
            attributes.SetColorMatrix(colorMatrix);

            //draw the original image on the new image
            //using the grayscale color matrix
            g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
               0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);

            //dispose the Graphics object
            g.Dispose();
            return newBitmap;
        }

        public static Bitmap ResizeImage(Image image, int width, int height)
        {
            //a holder for the result
            Bitmap result = new Bitmap(width, height);

            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(image, 0, 0, result.Width, result.Height);
            }

            //return the resulting bitmap
            return result;
        }

        public static void BoxieInvoke(Delegate m, params object[] args)
        {
            frmBoxie.instance.Invoke(m, args);
        }

        public static string CheckIPAlias(string s)
        {
            string items = BoxieRegLib.GetSettingString("Internet/Aliases", "");
            string[] itemArray = items.Split('/');
            for (int i = 0; i < itemArray.GetUpperBound(0); i++)
            {
                if (itemArray[i].Split(':')[0].ToLower() == s.ToLower())
                    return itemArray[i].Split(':')[1];
            }
            return s;
        }

        public static void SmartTyping(frmSmartTyping f, string lastcmd, frmBoxie b)
        {
            f.cmdCount = 0;
            SmartTypingHeader = "General Usage:";
            SmartHighlight(f.txt, lastcmd, "queue", "", "view, add, and remove the files in the queue");
            SmartHighlight(f.txt, lastcmd, "q", "", "view, add, and remove the files in the queue");
            SmartHighlight(f.txt, lastcmd, "config", "", "displays the configuration window");
            SmartHighlight(f.txt, lastcmd, "clipboard", "", "adds the clipboard image or text to the queue");
            SmartHighlight(f.txt, lastcmd, "clipboard:", "[name]", "adds clipboard image or text to queue using name [name]");
            SmartHighlight(f.txt, lastcmd, "cb", "", "adds the clipboard image to the queue");
            SmartHighlight(f.txt, lastcmd, "webdir", "", "launches web directory in your default web browser");
            SmartHighlight(f.txt, lastcmd, "www", "", "launches web directory in your default web browser");
            SmartHighlight(f.txt, lastcmd, "listen", "", "allows other Boxie's to connect to you");
            SmartHighlight(f.txt, lastcmd, "listen:", "[port]", "allows other Boxie's to connect to you on port [port]");
            SmartHighlight(f.txt, lastcmd, "connect:", "[alias/ip]", "attempts to connect to [alias/ip] if they are listening for you");
            SmartHighlight(f.txt, lastcmd, "update", "", "automatically updates your executable to the latest version");
            SmartHighlight(f.txt, lastcmd, "clear", "", "clears all files in the queue");
            SmartHighlight(f.txt, lastcmd, "about", "", "displays information about Boxie");
            SmartHighlight(f.txt, lastcmd, "help", "", "displays documentation in your default web browser");
            SmartHighlight(f.txt, lastcmd, "changelog", "", "displays the latest changes made to Boxie");
            SmartHighlight(f.txt, lastcmd, "changes", "", "displays the latest changes made to Boxie");
            SmartHighlight(f.txt, lastcmd, "exit", "", "closes Boxie");
            SmartHighlight(f.txt, lastcmd, "quit", "", "closes Boxie");
            SmartHighlight(f.txt, lastcmd, "x", "", "closes Boxie");
            SmartTypingHeader = "File Management:";
            SmartHighlight(f.txt, lastcmd, "upload", "", "uploads all files in the queue to the FTP");
            SmartHighlight(f.txt, lastcmd, "zip", "", "zips all files in the queue and adds resulting zip file to queue");
            SmartHighlight(f.txt, lastcmd, "zip:", "[name]", "zips all files in the queue into a zip called [name]");
            SmartHighlight(f.txt, lastcmd, "send", "", "sends all files to the connected remote Boxie");
            SmartHighlight(f.txt, lastcmd, "delete", "", "deletes all files in the queue from hard disk");
            SmartHighlight(f.txt, lastcmd, "del", "", "deletes all files in the queue from hard disk");
            SmartHighlight(f.txt, lastcmd, "md5hash", "", "dumps the queues md5 hashes into a text file");
            SmartTypingHeader = "Miscellaneous:";
            SmartHighlight(f.txt, lastcmd, "draw", "", "opens a drawing pad with the connected Boxie");
            SmartHighlight(f.txt, lastcmd, "tagmusic", "", "opens the music tagger with the files in the queue");
            SmartHighlight(f.txt, lastcmd, "textedit", "", "opens a real-time text editor with a connected Boxie");
            SmartTypingHeader = "Image Manipulation:";
            SmartHighlight(f.txt, lastcmd, "flipx", "", "flip image over the x-axis");
            SmartHighlight(f.txt, lastcmd, "flipy", "", "flip image over the y-axis");
            SmartHighlight(f.txt, lastcmd, "rotate90", "", "rotate image 90 degrees clockwise");
            SmartHighlight(f.txt, lastcmd, "rotate180", "", "rotate image 180 degrees clockwise");
            SmartHighlight(f.txt, lastcmd, "rotate270", "", "rotate image 270 degrees clockwise");
            SmartHighlight(f.txt, lastcmd, "grayscale", "", "convert the image to grayscale");
            SmartHighlight(f.txt, lastcmd, "gs", "", "convert the image to grayscale");
            SmartHighlight(f.txt, lastcmd, "scale:", "[1-999]", "scale the image by [1-999] percent");
            SmartHighlight(f.txt, lastcmd, "suffix:", "[text]", "appends [text] to end of filenames");
            SmartHighlight(f.txt, lastcmd, "osuffix:", "[text]", "appends [text] to end of old filenames");
            SmartHighlight(f.txt, lastcmd, "width:", "[#]", "sets the absolute width to [#] pixels");
            SmartHighlight(f.txt, lastcmd, "height:", "[#]", "sets the absolute height to [#] pixels");
            SmartHighlight(f.txt, lastcmd, "save", "", "overwrites original and saves as the same file type");
            SmartHighlight(f.txt, lastcmd, "savejpg", "", "saves changes to a new file as a jpg (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "savejpeg", "", "saves changes to a new file as a jpeg (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "savepng", "", "saves changes to a new file as a png (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "savegif", "", "saves changes to a new file as a gif (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "saveico", "", "saves changes to a new file as an ico (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "savebmp", "", "saves changes to a new file as a bmp (use as the last command)");
            SmartHighlight(f.txt, lastcmd, "savetiff", "", "saves changes to a new file as a tiff (use as the last command)");
            f.lockRtb(false);
            f.SetWindowHeight();
            f.txt.Refresh();
            f.RepositionWindow(b);
        }

        public static void SmartHighlight(RichTextBox rtb, string cmd, string matchcmd, string additionalcmd, string desc)
        {
            // if cmd is larger than realcmd, just return now
            if ((cmd.Length > matchcmd.Length)&&(additionalcmd==""))
                return;
            // okay, same size or smaller - include this to results?
            for (int i = 0; i < cmd.Length; i++)
                if(matchcmd.Length > i)
                    if (cmd.Substring(i, 1) != matchcmd.Substring(i, 1))
                        return;
            // okay, so far so good - continue!
            bool isbold = true;
            if (rtb.Text != "")
            {
                rtb.SelectionStart = rtb.TextLength;
                rtb.SelectedText = Environment.NewLine;
            }
            rtb.SelectionFont = new Font("Candara", 9, FontStyle.Bold);
            // header?
            if (SmartTypingHeader != "")
            {
                rtb.SelectionFont = new Font("Candara", 10, FontStyle.Bold);
                rtb.SelectionStart = rtb.TextLength;
                rtb.SelectedText = SmartTypingHeader + Environment.NewLine;
                rtb.SelectionFont = new Font("Candara", 9, FontStyle.Bold);
                SmartTypingHeader = "";
            }
            for (int i = 0; i < matchcmd.Length; i++)
            {
                if (cmd.Length > i) // length greater than 0 (length of 1)
                {
                    if ((cmd.Substring(i, 1) != matchcmd.Substring(i, 1)) && (isbold))
                    {
                        rtb.SelectionFont = new Font("Candara", 9, FontStyle.Regular);
                        isbold = false;
                    }
                }
                else if (isbold)
                {
                    rtb.SelectionFont = new Font("Candara", 9, FontStyle.Regular);
                    isbold = false;
                }

                rtb.SelectionStart = rtb.TextLength;
                rtb.SelectedText = matchcmd.Substring(i, 1);
            }
            if(isbold)
                rtb.SelectionFont = new Font("Candara", 9, FontStyle.Regular);
            rtb.SelectedText = additionalcmd + " - " + desc;
            frmBoxie.instance.fS.cmdCount++;
            rtb.Tag = matchcmd;
        }

        public static void ZipQueuedFiles(string zippath)
        {
            frmBoxie.instance.fL.add("Adding " + frmBoxie.instance.appargs.Length.ToString() + " files to zip..", 2);
            frmBoxie.instance.fL.add("Zip Output: <AppPath>\\" + System.IO.Path.GetFileName(zippath), 6);
            try
            {
                // zip
                ZipStorer zip = ZipStorer.Create(zippath, "Zipped with Boxie");
                foreach (string path in frmBoxie.instance.appargs)
                {
                    zip.AddFile(ZipStorer.Compression.Deflate, path, System.IO.Path.GetFileName(path), "");
                }
                zip.Close();
                frmBoxie.instance.fL.add("Zip operation complete!", 4);
                // remove files in queue, add zip file
                frmBoxie.instance.appargs = new string[1] { zippath };
                if(frmBoxie.instance.fQ!=null)
                    if(frmBoxie.instance.fQ.Visible)
                    {
                        frmBoxie.instance.fQ.lst.Items.Clear();
                        frmBoxie.instance.fQ.lst.Items.Add(zippath);
                    }
                // update Boxie title
                frmBoxie.instance.Text = frmBoxie.instance.appnamebuild + "1 Files Loaded";
            }
            catch (Exception e)
            {
                frmBoxie.instance.fL.add("Zip operation failed! An error has occurred.", 3, e.Message);
            }   
        }

        public static bool allFileType(string ft)
        {
            string[] a = Boxie.frmBoxie.instance.appargs;
            for (int i = 0; i < a.Length; i++)
            {
                if (System.IO.Path.GetExtension(a[i]).ToLower() != ft)
                    return false;
            }
            return true;
        }
    }
}
